#ifndef PARSER_H
#define PARSER_H

#include "list.h"

#define TEST(x)    (parser_get_cur_token() == x)
#define OR(x)      || (parser_get_cur_token() == x)
#define TYPE_FIRST TEST(INT) OR(CHAR) OR(VOID)

// <decl_head> 后面可能出现的符号
#define DECL_HEAD_FOLLOW  TEST(SEMICO) OR(COMMA) OR(ASSIGN) OR(LPAREN) OR(LBRACKET)

#define EXPR_FIRST                                                      \
    TEST(LPAREN)                                                        \
    OR(NUM) OR(CHARA) OR(STRING) OR(ID) OR(NOT) OR(SUB) OR(LEA) OR(MUL) \
        OR(INC) OR(DEC) OR(ADD) OR(SIZEOF) //13个

#define STATEMENT_FIRST                                                \
    EXPR_FIRST OR(SEMICO) OR(WHILE) OR(FOR) OR(DO) OR(IF) OR(SWITCH) \
        OR(RETURN) OR(BREAK) OR(CONTINUE) // 22个

#define EXPR_STAT_FOLLOW  STATEMENT_FIRST OR(CHAR)OR(INT)OR(VOID)OR(CASE)OR(DEFAULT)\
 OR(ELSE)OR(EXTERN)OR(RBRACES)OR(LBRACES)  // 31个

#define VAR_LIST_FOLLOW         STATEMENT_FIRST OR(CHAR)OR(INT)OR(VOID)OR(EXTERN)OR(LBRACES)OR(RBRACES)
#define CONTINUE_STAT_FOLLOW    EXPR_STAT_FOLLOW
#define BREAK_STAT_FOLLOW       EXPR_STAT_FOLLOW
#define SWITCH_STAT_FOLLOW      EXPR_STAT_FOLLOW
#define LOCAL_DECL_FOLLOW       STATEMENT_FIRST OR(CHAR)OR(INT)OR(VOID)OR(EXTERN)OR(RBRACES)OR(LBRACES)

#define SUBPROGRAM_FIRST                STATEMENT_FIRST OR(CHAR)OR(INT)OR(VOID)OR(LBRACES) OR(EXTERN) // 27 个
#define SUBPROGRAM_IN_SWITCH_FIRST      STATEMENT_FIRST OR(LBRACES) 
#define PROGRAM_FIRST                   TYPE_FIRST OR(EXTERN)


#define SCOPE_GLOBAL 1 // 文件作用域
#define SCOPE_LOCAL  2
#define NOT_ARR           (-2)
#define ARR_SIZE_INVALID  (-1)
#define ARR_SIZE_UNKNOWN  (0)

void next_token(void);
void syntax_analyse(void);
symbol_e parser_get_cur_token(void);
const char *parser_get_token_str(void);
const char parser_get_token_ch(void);
const int parser_get_token_num(void);
void destroy_realarg(struct list_head * params_head);
const int parser_get_token_line_num(void);

#endif